<script setup lang="ts">
import {DataTableColumns, FormInst, FormItemRule, FormRules, NButton, NButtonGroup, NSpace, NTag} from "naive-ui";
import type {SysDept} from "@/api/dept/types.ts";
import {deptApi} from "@/api/dept";
import {renderPermission, resetToNull} from "@/utils";
import {useDictStore} from "@/stores";
import DeptDiagram from "@/views/system-manage/dept-manage/dept-diagram/index.vue"

enum ModeTypeEnum {
  ADD = '新增',
  MODIFY = '修改',
  DETAIL = '详情'
}

const dictStore = useDictStore();
const fixValueLoading = ref(false)
const drawerDetailShow = ref(false)
const drawerDetailTitle = ref('')
const drawerDetailFormRef = ref<FormInst | null>(null)
const drawerDetailFormParentTreeOptions = ref<SysDept[]>([])
const drawerDetailFormRules = reactive<FormRules>({
  deptCode: {
    required: true,
    trigger: 'blur',
    validator: (rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error('部门编码不能为空')
      }
      if (value.length > 20) {
        return new Error('部门编码长度不能超过20个字符')
      }
      const reg = /^[a-zA-Z0-9_]+$/
      if (!reg.test(value)) {
        return new Error('部门编码只能是大小写字母、数字、下划线')
      }
    }
  },
  deptName: {
    required: true,
    trigger: 'blur',
    validator: (rule: FormItemRule, value: string) => {
      if (!value) {
        return new Error('部门名称不能为空')
      }
      if (value.length > 20) {
        return new Error('部门名称长度不能超过20个字符')
      }
    }
  }
})
const drawerDetailFormModel = reactive<SysDept>(<SysDept>{})
const drawerDetailFormLoading = ref(false)
const tableLoading = ref(false)
const tableColumns = ref<DataTableColumns<SysDept>>([
  {title: '部门编码', key: 'deptCode'},
  {title: '部门名称', key: 'deptName'},
  {title: '部门权重', key: 'deptWeight'},
  {title: '部门层级', key: 'deptLevel'},
  {title: '部门状态', key: 'deptStatus', render: row => dictStore.renderTag('common-status', row.deptStatus)},
  {title: '操作', key: 'action', align: 'center', render: (row: SysDept) => tableActionRender(row)}
])
const tableData = ref<SysDept[]>([])

const modalDeptDiagramShow = ref(false)

onMounted(() => {
  dictStore.loadDict(['common-status'])
  handleClickQuery()
})

const tableActionRender = (row: SysDept) => {
  return h(NButtonGroup, {size: 'small'}, {
    default: () => [
      renderPermission(h(NButton, {
        tertiary: true,
        type: 'default',
        onClick: () => handleClickDetail(row)
      }, {default: () => '详情'}), 'dept:detail'),
      renderPermission(h(NButton, {
        tertiary: true,
        type: 'primary',
        onClick: () => handleClickModify(row)
      }, {default: () => '修改'}), 'dept:modify'),
      renderPermission(h(NButton, {
        tertiary: true,
        type: 'info',
        onClick: () => handleClickAdd(row.id)
      }, {default: () => '新增下级'}), 'dept:add')
    ]
  })
}

const handleClickQuery = () => {
  tableLoading.value = true
  deptApi.tree().then(res => {
    tableData.value = res.data
  }).finally(() => tableLoading.value = false)
}
const handleClickDiagram = () => {
  modalDeptDiagramShow.value = true
}
const handleClickFixValue = () => {
  fixValueLoading.value = true
  deptApi.fixValue().then(res => {
    window.$message?.success(res.message)
    handleClickQuery()
  }).finally(() => fixValueLoading.value = false);
}
const initDrawerDetail = (type: ModeTypeEnum) => {
  drawerDetailTitle.value = type
  drawerDetailShow.value = true
  deptApi.tree().then(res => {
    drawerDetailFormParentTreeOptions.value = res.data
  })
}
const handleClickAdd = (parentId?: string) => {
  initDrawerDetail(ModeTypeEnum.ADD)
  drawerDetailFormModel.deptStatus = dictStore.getDictDefault('common-status').dictValue as number
  drawerDetailFormModel.deptWeight = 0
  if (parentId) {
    drawerDetailFormModel.parentId = parentId
  }
}

const handleClickDetail = (row: SysDept) => {
  if (row.id) {
    deptApi.detail(row.id).then(res => {
      Object.assign(drawerDetailFormModel, res.data)
      initDrawerDetail(ModeTypeEnum.DETAIL)
    })
  }
}

const handleClickModify = (row: SysDept) => {
  if (row.id) {
    deptApi.detail(row.id).then(res => {
      Object.assign(drawerDetailFormModel, res.data)
      initDrawerDetail(ModeTypeEnum.MODIFY)
    })
  }
}

const handleClickSubmit = () => {
  drawerDetailFormRef.value?.validate((errors) => {
    if (!errors) {
      drawerDetailFormLoading.value = true
      switch (drawerDetailTitle.value) {
        case ModeTypeEnum.ADD:
          deptApi.add(drawerDetailFormModel).then(res => {
            window.$message?.success(res.message)
            drawerDetailShow.value = false
          })
          break
        case ModeTypeEnum.MODIFY:
          deptApi.modify(drawerDetailFormModel).then(res => {
            window.$message?.success(res.message)
            drawerDetailShow.value = false
          })
          break
      }
    }
  }).finally(() => drawerDetailFormLoading.value = false)
}
const handleDrawerClose = () => {
  drawerDetailShow.value = false
  resetToNull(drawerDetailFormModel)
  handleClickQuery()
}
</script>
<template>
  <n-card class="dept-manage">
    <template #header>
      <n-space>
        <n-button
            secondary
            @click="handleClickQuery"
            v-p="'dept:tree'"
        >查询
        </n-button>
        <n-button
            secondary
            type="primary"
            @click="handleClickAdd()"
            v-p="'dept:add'"
        >新增
        </n-button>
        <n-button
            secondary
            type="info"
            :disabled="tableData.length === 0"
            @click="handleClickDiagram"
            v-p="'dept:diagram'"
        >图例
        </n-button>
        <n-button
            secondary
            type="warning"
            :disabled="tableData.length === 0"
            @click="handleClickFixValue"
            :loading="fixValueLoading"
            v-p="'dept:fix-value'"
        >修复值
        </n-button>
      </n-space>
    </template>
    <n-data-table
        remote
        :loading="tableLoading"
        :columns="tableColumns"
        :data="tableData"
        :row-key="(row:SysDept) => row.id"
    />
  </n-card>
  <n-drawer
      v-model:show="drawerDetailShow"
      :width="502"
      :on-after-leave="handleDrawerClose">
    <n-drawer-content
        :title="drawerDetailTitle"
        closable
    >
      <n-form
          ref="drawerDetailFormRef"
          :model="drawerDetailFormModel"
          :rules="drawerDetailFormRules"
          :disabled="drawerDetailTitle === ModeTypeEnum.DETAIL"
      >
        <n-grid :cols="24" :x-gap="12">
          <n-form-item-gi v-if="drawerDetailFormModel.id" :span="24" label="主键">
            <n-tag type="primary">{{ drawerDetailFormModel.id }}</n-tag>
          </n-form-item-gi>
          <n-form-item-gi :span="24" label="上级部门">
            <n-tree-select
                clearable
                :options="drawerDetailFormParentTreeOptions"
                label-field="deptName"
                key-field="id"
                v-model:value="drawerDetailFormModel.parentId"
            />
          </n-form-item-gi>
          <n-form-item-gi :span="24" label="部门编码" path="deptCode">
            <n-input v-model:value="drawerDetailFormModel.deptCode"/>
          </n-form-item-gi>
          <n-form-item-gi :span="24" label="部门名称" path="deptName">
            <n-input v-model:value="drawerDetailFormModel.deptName"/>
          </n-form-item-gi>
          <n-form-item-gi :span="12" label="排序" path="deptWeight">
            <n-input-number v-model:value="drawerDetailFormModel.deptWeight"/>
          </n-form-item-gi>
          <n-form-item-gi :span="12" label="状态" path="deptStatus">
            <n-switch
                v-model:value="drawerDetailFormModel.deptStatus"
                :checked-value="1"
                :unchecked-value="0"
            />
          </n-form-item-gi>
          <template v-if="drawerDetailTitle !== ModeTypeEnum.ADD">
            <n-form-item-gi :span="8" label="部门层级">
              {{ drawerDetailFormModel.deptLevel }}
            </n-form-item-gi>
            <n-form-item-gi :span="8" label="左值">
              {{ drawerDetailFormModel.leftValue }}
            </n-form-item-gi>
            <n-form-item-gi :span="8" label="右值">
              {{ drawerDetailFormModel.rightValue }}
            </n-form-item-gi>
          </template>
        </n-grid>
      </n-form>
      <template #footer>
        <n-button type="primary" @click="handleClickSubmit" :loading="drawerDetailFormLoading">提交</n-button>
      </template>
    </n-drawer-content>
  </n-drawer>
  <n-modal
      v-model:show="modalDeptDiagramShow"
      preset="card"
      w800px
      size="huge"
      title="图例"
      :bordered="false"
  >
    <dept-diagram/>
  </n-modal>
</template>
<style scoped>
</style>
